# import pymysql
# class DB():
#     # 初始化操作
#     def __init__(self,**kwargs):
#         '''
#
#         :param host: 数据库域名
#         :param port: 数据库端口号
#         :param user: 数据库用户名
#         :param password: 数据库密码
#         :param database: 数据库名
#         '''
#         self.connent=pymysql.connect(**kwargs)
#         self.cursor=self.connent.cursor()
#
#     # 执行查询操作
#     def db_select(self,sql,params=None):
#         '''
#
#         :param sql: 数据库命令
#         :param params: 使用占位符，方式sql语句注入
#         :return: 返回数据库查询到的数据
#         '''
#         try:
#             self.cursor.execute(sql,params)
#             return self.cursor.fetchall()
#         except Exception as e:
#             print(f"删除失败，错误：{e}")
#             return 0
#     # 执行删除操作
#     def db_delete(self,sql,params=None):
#         '''
#
#         :param sql: 数据库命令
#         :param params: 使用占位符，方式sql语句注入
#         :return:
#         '''
#         try:
#             self.cursor.execute(sql, params)
#             self.connent.commit()
#             return self.cursor.rowcount
#         except Exception as e:
#             print(f"删除失败，错误：{e}")
#             return 0
#     # 关闭数据库操作
#     def db_close(self):
#         self.cursor.close()
#         self.connent.close()

import pymysql
from pymysql import OperationalError
import time


class DB():
    # 初始化操作
    def __init__(self, max_reconnect_attempts=3, reconnect_delay=1, **kwargs):
        '''
        :param host: 数据库域名
        :param port: 数据库端口号
        :param user: 数据库用户名
        :param password: 数据库密码
        :param database: 数据库名
        :param max_reconnect_attempts: 最大重连次数
        :param reconnect_delay: 重连间隔时间(秒)
        '''
        self.kwargs = kwargs
        self.max_reconnect_attempts = max_reconnect_attempts
        self.reconnect_delay = reconnect_delay
        self.conn = None
        self.cursor = None
        # 初始化连接
        self._connect()

    # 建立数据库连接
    def _connect(self):
        try:
            # 关闭可能存在的旧连接
            if self.conn:
                self.db_close()

            self.conn = pymysql.connect(**self.kwargs)
            self.cursor = self.conn.cursor()
            print("数据库连接成功")
            return True
        except Exception as e:
            print(f"数据库连接失败: {e}")
            return False

    # 检查连接是否有效，无效则尝试重连
    def _check_connection(self):
        if not self.conn or not self.cursor:
            return self._reconnect()

        try:
            # 尝试执行一个简单的查询来检查连接
            self.conn.ping(reconnect=False)
            return True
        except (OperationalError, ConnectionAbortedError):
            print("数据库连接已断开，尝试重连...")
            return self._reconnect()

    # 重连机制
    def _reconnect(self):
        for attempt in range(self.max_reconnect_attempts):
            if self._connect():
                return True
            print(f"重连失败，将在{self.reconnect_delay}秒后进行第{attempt + 2}次尝试...")
            time.sleep(self.reconnect_delay)
        print(f"达到最大重连次数({self.max_reconnect_attempts})，重连失败")
        return False

    # 执行查询操作
    def db_select(self, sql, params=None):
        '''
        :param sql: 数据库命令
        :param params: 使用占位符，防止sql语句注入
        :return: 返回数据库查询到的数据
        '''
        # 检查连接状态
        if not self._check_connection():
            return 0

        try:
            self.cursor.execute(sql, params)
            return self.cursor.fetchall()
        except Exception as e:
            print(f"查询失败，错误：{e}")
            # 失败时尝试重新连接一次
            if self._reconnect():
                try:
                    self.cursor.execute(sql, params)
                    return self.cursor.fetchall()
                except Exception as e2:
                    print(f"重新查询失败，错误：{e2}")
                    return 0
            return 0

    # 执行删除操作
    def db_delete(self, sql, params=None):
        '''
        :param sql: 数据库命令
        :param params: 使用占位符，防止sql语句注入
        :return: 受影响的行数
        '''
        # 检查连接状态
        if not self._check_connection():
            return 0

        try:
            self.cursor.execute(sql, params)
            self.conn.commit()
            return self.cursor.rowcount
        except Exception as e:
            self.conn.rollback()
            print(f"删除失败，错误：{e}")
            # 失败时尝试重新连接一次
            if self._reconnect():
                try:
                    self.cursor.execute(sql, params)
                    self.conn.commit()
                    return self.cursor.rowcount
                except Exception as e2:
                    self.conn.rollback()
                    print(f"重新删除失败，错误：{e2}")
                    return 0
            return 0




    # 关闭数据库操作
    def db_close(self):
        try:
            if self.cursor:
                self.cursor.close()
                self.cursor = None
            if self.conn:
                self.conn.close()
                self.conn = None
            print("数据库连接已关闭")
        except Exception as e:
            print(f"关闭数据库连接时出错：{e}")

